#include "dvbinner.h"
#include "dvbtsdb.h"
#include "dvbtsparser.h"


int DVBTSGetTunerInfoByServiceHandle(dvb_service_t* SerHandle, dvb_tuner_t* pstTunerinfo)
{
	int s32Ret = -1;
	TSDATA *pstTs;

	if(SerHandle && pstTunerinfo)
	{
		pstTs = DVBTSDBSearchTS(SerHandle->netId, SerHandle->tsId, SerHandle->frequence);
		if(pstTs)
		{
			memcpy(pstTunerinfo, &pstTs->tunerParams, sizeof(dvb_tuner_t));
			s32Ret = 0;
		}
	}
	else
	{
		mwError("DVBTSGetTunerInfoByServiceHandle() - invalid parametor, SerHandle = %p, pstTunerinfo = %p\r\n", SerHandle, pstTunerinfo);
	}
	
	return s32Ret;
}


unsigned short DVBTSGetServicePCRPID(dvb_service_t* handle)
{
	unsigned short serviceid;
	TSDATA *ts;
	SECTIONDATA *sd;
	unsigned short u16PcrPid = 0;

	if (handle)	
	{
		ts = DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);
		if(ts)
		{
			sd=ts->pmt->sections;
			while(sd)																		
			{
				serviceid = SiPsiPMTGetServiceID(sd->Data);
				if(serviceid==handle->serviceId)
				{
					u16PcrPid = SiPsiPMTGetPCRPID(sd->Data);
					break;
				}
				sd=sd->next;
			}
		}
	}
	return u16PcrPid;
}

int DVBTSGetServicePmtPidParams(dvb_service_t* handle, sipsi_prog_element_t *pprogelement)
{
	unsigned short serviceid;
	TSDATA *ts;
	SECTIONDATA *sd;
	unsigned char *section;
	int j,ec=0,count=0;

	if(handle)
	{
		ts = DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);
		if(ts!=NULL)
		{
			sd=ts->pmt->sections;
			while(sd)																					
			{
				section=sd->Data;
				serviceid = SiPsiPMTGetServiceID(section);
				if(serviceid==handle->serviceId)
				{
					ec=SiPsiPMTGetElementCount(section);
					for(j=0;	j<ec;	j++)
					{
						SiPsiPMTGetElement(section,&pprogelement[j],j);
					}
					break;
				}
				sd=sd->next;
			}
		}
	}
	return ec;
}

int DVBTSGetServicePmtPids(dvb_service_t* handle, PIDINFO *pidinfo)
{
	sipsi_ecminfo_t ecminfo[10];
	unsigned short serviceid;
	TSDATA *ts;
	SECTIONDATA *sd;
	sipsi_prog_element_t progelement;
	unsigned char *section;
	int i,j,ret,ec=0, count;
	int psEcmCnt=0, esEcmCnt=0;

	if(handle)
	{
		ts = DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);
		if(ts != NULL)
		{
			sd=ts->pmt->sections;
			while(sd)																					
			{
				section=sd->Data;
				serviceid = SiPsiPMTGetServiceID(section);
				if(serviceid==handle->serviceId)
				{
					psEcmCnt=SiPsiPMTGetCAInfoCount((unsigned char *)section+12, SiPsiPMTGetProgramInfoLen(section));
					for (i=0;i<psEcmCnt;i++)
					{
						ret=SiPsiPMTGetCAInfo((unsigned char *)section+12, SiPsiPMTGetProgramInfoLen(section), i, &(ecminfo[i]));
					}
					ec=SiPsiPMTGetElementCount(section);
					for(j=0;	j<ec; j++)
					{
						SiPsiPMTGetElement(section,&progelement,j);
						if(pidinfo)
						{
							pidinfo[j].type=progelement.m_u8StreamType;
							pidinfo[j].pid=progelement.m_u16ElementaryPid;

							if (progelement.m_u16EsInfoLength>0)
							{
								esEcmCnt = SiPsiPMTGetCAInfoCount((unsigned char *)progelement.m_pu8Descriptors, progelement.m_u16EsInfoLength);
								for (i=0;i<esEcmCnt;i++)
									ret=SiPsiPMTGetCAInfo((unsigned char *)progelement.m_pu8Descriptors, SiPsiPMTGetProgramInfoLen(section), i, &(ecminfo[i]));
							}	

							if(esEcmCnt)
							{
								count = esEcmCnt;
							}
							else
							{
								count = psEcmCnt;
							}

							pidinfo[j].ecmNum=count;
							for (i=0;i<count;i++)
							{
								pidinfo[j].ecmInfo[i].CAID =ecminfo[i].m_u16CaId;
								pidinfo[j].ecmInfo[i].PID =ecminfo[i].m_u16Pid;
							}
							
							if(esEcmCnt)
							{
								memset(ecminfo, 0, sizeof(ecminfo));
							}
							if (progelement.m_u16EsInfoLength >0)
							{
								unsigned char*des=SiPsiFindDescriptor(progelement.m_pu8Descriptors, progelement.m_u16EsInfoLength, SIPSI_DESCTAG_STREAM_IDENTIFIER);
								if (des !=NULL)
								{
									pidinfo[j].ComponentTag=des[2];
								}
							}						
						}	
					}
					return ec;
				}
				sd=sd->next;
			}
		}
	}
	return ec;
}

int DVBTSGetServicePIDS(dvb_service_t* handle,unsigned short *pcrPID,unsigned short *vID,unsigned short *aIDs)
{
	int count,i,ac,rc;

	unsigned short serviceid;
	TSDATA *ts = DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);
	SECTIONDATA *sd;
	sipsi_prog_element_t p;
	char* ps8RegisterationDesc;
	unsigned short u16PrivateEsPid = 0;
	
	*vID=0x1fff;
	*pcrPID=0x1fff;
	ac=0;
	rc=0;
	if(ts)
	{
		sd=ts->pmt->sections;
		while(sd)
		{
			serviceid = SiPsiPMTGetServiceID(sd->Data);
			if(serviceid==handle->serviceId)
			{
				count=SiPsiPMTGetElementCount(sd->Data);
				for(i=0; i<count; i++)
				{
					SiPsiPMTGetElement(sd->Data,&p,i);
					switch(p.m_u8StreamType)
					{
						case SIPSI_ES_TYPE_MPEG1_VIDEO:
						case SIPSI_ES_TYPE_MPEG2_VIDEO:
						case SIPSI_ES_TYPE_MPEG4_VIDEO:
						case SIPSI_ES_TYPE_VIDEO_HEVC:
						case SIPSI_ES_TYPE_VIDEO_CAVS:
							if (vID)
								*vID=p.m_u16ElementaryPid;
							rc++;
							break;
						case SIPSI_ES_TYPE_MPEG1_AUDIO:
						case SIPSI_ES_TYPE_MPEG2_AUDIO:
						case SIPSI_ES_TYPE_AAC:
						case SIPSI_ES_TYPE_AAC1:
						case SIPSI_ATSC_DOLBY_DIGITAL:
						case SIPSI_ES_TYPE_DTS_AUDIO:
							if (aIDs)
								aIDs[ac++]=p.m_u16ElementaryPid;
							rc++;
							break;
						case SIPSI_ES_TYPE_PRIVATE_PES:
							if(SiPsiFindDescriptor(p.m_pu8Descriptors, p.m_u16EsInfoLength, SIPSI_DESCTAG_AC3))
							{
								if (aIDs)
									aIDs[ac++]=p.m_u16ElementaryPid;
								rc++;
							}
							else if(SiPsiFindDescriptor(p.m_pu8Descriptors, p.m_u16EsInfoLength, SIPSI_DESCTAG_REGISTERATION))
							{
								ps8RegisterationDesc = SiPsiFindDescriptor(p.m_pu8Descriptors, p.m_u16EsInfoLength, SIPSI_DESCTAG_REGISTERATION);
								if(ps8RegisterationDesc[1]==4 && ps8RegisterationDesc[2]=='H' && ps8RegisterationDesc[3]=='E' && ps8RegisterationDesc[4]=='V' && ps8RegisterationDesc[5]=='C')
								{
									if (vID)
										*vID=p.m_u16ElementaryPid;
									rc++;
								}
								else if((ps8RegisterationDesc[1]==4 && ps8RegisterationDesc[2]=='A' && ps8RegisterationDesc[3]=='V' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='V'))
								{
									if (vID)
										*vID=p.m_u16ElementaryPid;
									rc++;
								}
								else if(ps8RegisterationDesc[1]==4 && (ps8RegisterationDesc[2]=='A' && ps8RegisterationDesc[3]=='C' && ps8RegisterationDesc[4]=='-' && ps8RegisterationDesc[5]=='3')
									|| (ps8RegisterationDesc[2]=='D' && ps8RegisterationDesc[3]=='T' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='1')
									|| (ps8RegisterationDesc[2]=='D' && ps8RegisterationDesc[3]=='T' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='2')
									|| (ps8RegisterationDesc[2]=='D' && ps8RegisterationDesc[3]=='T' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='3')
									|| (ps8RegisterationDesc[2]=='E' && ps8RegisterationDesc[3]=='A' && ps8RegisterationDesc[4]=='C' && ps8RegisterationDesc[5]=='3'))
								{
									if (aIDs)
										aIDs[ac++]=p.m_u16ElementaryPid;
									rc++;
								}

							}
							else if(u16PrivateEsPid == 0)
							{
								u16PrivateEsPid = p.m_u16ElementaryPid;
							}
							break;
						default:
							break;
					}
				}
				if(pcrPID)
					*pcrPID=SiPsiPMTGetPCRPID(sd->Data);
				if(ac == 0 && u16PrivateEsPid != 0)
				{
					rc++;
					aIDs[ac++]=(SIPSI_ES_TYPE_PRIVATE_PES<<16)|u16PrivateEsPid;
				}
				return rc+1;
			}
			sd=sd->next;
		}
	}
	return 0;
}

int DVBTSGetServicePIDSEx(dvb_service_t* handle,unsigned int *pcrPID, unsigned int *vID,unsigned int*aIDs)
{
	int count,i,ac,rc;
	unsigned short serviceid;
	TSDATA *ts;
	SECTIONDATA *sd;
	sipsi_prog_element_t p;
	char* ps8RegisterationDesc;
	unsigned short u16PrivateEsPid = 0;

	ts = DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);
	*vID=0x1fff;
	 *pcrPID=0x1fff;
	ac=0;
	rc=0;
	if(ts)
	{
		sd=ts->pmt->sections;
		while(sd)	
		{
			serviceid = SiPsiPMTGetServiceID(sd->Data);
			if(serviceid==handle->serviceId)
			{
				count=SiPsiPMTGetElementCount(sd->Data);
				for(i=0; i<count; i++)
				{
					SiPsiPMTGetElement(sd->Data,&p,i);
					switch(p.m_u8StreamType)
					{
						case SIPSI_ES_TYPE_MPEG1_VIDEO:
						case SIPSI_ES_TYPE_MPEG2_VIDEO:
						case SIPSI_ES_TYPE_MPEG4_VIDEO:
						case SIPSI_ES_TYPE_VIDEO_HEVC:
						case SIPSI_ES_TYPE_VIDEO_CAVS:
							if (vID)
								*vID=(p.m_u8StreamType<<16)|p.m_u16ElementaryPid;
							rc++;
							break;
						case SIPSI_ES_TYPE_MPEG1_AUDIO:
						case SIPSI_ES_TYPE_MPEG2_AUDIO:
						case SIPSI_ES_TYPE_AAC:
						case SIPSI_ES_TYPE_AAC1:
						case SIPSI_ATSC_DOLBY_DIGITAL:
						case SIPSI_ES_TYPE_DTS_AUDIO:
							if (aIDs)
								aIDs[ac++]=(p.m_u8StreamType<<16)|p.m_u16ElementaryPid;
							rc++;
							break;
						case SIPSI_ES_TYPE_PRIVATE_PES:
							if(SiPsiFindDescriptor(p.m_pu8Descriptors, p.m_u16EsInfoLength, SIPSI_DESCTAG_AC3))
							{
								if (aIDs)
									aIDs[ac++]=(p.m_u8StreamType<<16)|p.m_u16ElementaryPid;
								rc++;
							}
							else if(SiPsiFindDescriptor(p.m_pu8Descriptors, p.m_u16EsInfoLength, SIPSI_DESCTAG_REGISTERATION))
							{
								ps8RegisterationDesc = SiPsiFindDescriptor(p.m_pu8Descriptors, p.m_u16EsInfoLength, SIPSI_DESCTAG_REGISTERATION);
								if(ps8RegisterationDesc[1]==4 && ps8RegisterationDesc[2]=='H' && ps8RegisterationDesc[3]=='E' && ps8RegisterationDesc[4]=='V' && ps8RegisterationDesc[5]=='C')
								{
									if (vID)
										*vID=(SIPSI_ES_TYPE_VIDEO_HEVC<<16)|p.m_u16ElementaryPid;
									rc++;
								}
								else if((ps8RegisterationDesc[1]==4 && ps8RegisterationDesc[2]=='A' && ps8RegisterationDesc[3]=='V' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='V'))
								{
									if (vID)
										*vID=(SIPSI_ES_TYPE_VIDEO_CAVS<<16)|p.m_u16ElementaryPid;
									rc++;
								}
								else if(ps8RegisterationDesc[1]==4 && (ps8RegisterationDesc[2]=='A' && ps8RegisterationDesc[3]=='C' && ps8RegisterationDesc[4]=='-' && ps8RegisterationDesc[5]=='3')
									|| (ps8RegisterationDesc[2]=='D' && ps8RegisterationDesc[3]=='T' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='1')
									|| (ps8RegisterationDesc[2]=='D' && ps8RegisterationDesc[3]=='T' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='2')
									|| (ps8RegisterationDesc[2]=='D' && ps8RegisterationDesc[3]=='T' && ps8RegisterationDesc[4]=='S' && ps8RegisterationDesc[5]=='3')
									|| (ps8RegisterationDesc[2]=='E' && ps8RegisterationDesc[3]=='A' && ps8RegisterationDesc[4]=='C' && ps8RegisterationDesc[5]=='3'))
								{
									if (aIDs)
										aIDs[ac++] = (p.m_u8StreamType<<16)|p.m_u16ElementaryPid;
									rc++;
								}

							}
							else if(u16PrivateEsPid == 0)
							{
								u16PrivateEsPid = (p.m_u8StreamType<<16)|p.m_u16ElementaryPid;
							}
							break;
						default:
							break;
					}
				}
				if(pcrPID)
					*pcrPID=SiPsiPMTGetPCRPID(sd->Data);
				if(ac == 0 && u16PrivateEsPid != 0)
				{
					rc++;
					aIDs[ac++]=(SIPSI_ES_TYPE_PRIVATE_PES<<16)|u16PrivateEsPid;
				}
				return rc+1;
			}
			sd=sd->next;
		}
	}
	return 0;
}

//pu8Pmt: 1024Bytes buffer
int DVBTSGetPmt(dvb_service_t* handle, unsigned char* pu8Pmt, unsigned short *pu16Len)
{
	unsigned int count;
	int rc = -1;
	unsigned short serviceid;
	unsigned short secLen;
	SECTIONDATA *sd;
	sipsi_prog_element_t p;

	TSDATA *ts= DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);

	mwDebug("DVBTSGetPmt() - entry, handle[%d, %d, %d,%d]\n", handle->netId, handle->tsId, handle->serviceId,handle->frequence);

	if(!pu8Pmt || !pu16Len)
		return -1;

	*pu16Len = 0;
	if(ts)
	{
		sd=ts->pmt->sections;
		while(sd)
		{
			serviceid = SiPsiPMTGetServiceID(sd->Data);
			if(serviceid==handle->serviceId)
			{
				secLen = SiPsiGetSectionLength(sd->Data);
				secLen += 3;
				if(secLen < 1024)
				{
					memcpy(pu8Pmt, sd->Data, secLen);
					*pu16Len = secLen;
					rc = 0;
				}
				else
				{
					mwDebug("DVBTSGetPmt() - found pmt section len > 1024 Bytes\r\n");
				}
				break;
			}
			sd=sd->next;
		}
	}
	
	mwDebug("DVBTSGetPmt() - return, handle[%d, %d, %d,%d], pu16Len = %d, rc = %d\n", handle->netId, handle->tsId, handle->serviceId,handle->frequence,*pu16Len, rc);

	return rc;
}

int DVBTSGetPmtPid(dvb_service_t* handle, unsigned short *pu16Pid)
{
	int rc = -1;
	TSDATA *ts;
	SECTIONDATA *sd;
	unsigned int u32ProgCnt;
	unsigned int i;
	sipsi_program_t prg;
	
	ts = DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);
	if(pu16Pid && ts)
	{
		*pu16Pid = 0;
		sd = ts->pat->sections;
		while(sd)
		{
			u32ProgCnt = SiPsiPATGetProgramCount(sd->Data);
			for(i=0; i<u32ProgCnt; i++)
			{
				SiPsiPATGetProgram(sd->Data, &prg, i);
				if(prg.m_u16ProgNum == handle->serviceId)
				{
					*pu16Pid = prg.m_u16PmtPid;
					break;
				}
			}
			if(i < u32ProgCnt)
			{
				rc = 0;
				break;
			}
		}
	}

	mwDebug("DVBTSGetPmtPid() - pmt pid = %d, rc = %d", *pu16Pid, rc);
	return rc;
}

static int DVBTSFindService(TSDATA *ts, unsigned short serviceID, sipsi_dvbservice_t *service)
{
	SECTIONDATA *sd;
	unsigned int i;
	unsigned int sCount;
	sipsi_dvbservice_t svr;
	int s32Ret = -1;
	
	if(ts->sdt && ts->sdt->sections)
	{
		sd=ts->sdt->sections;
		while(sd)
		{
			sCount= SiPsiSDTGetServiceCount(sd->Data);
			for(i=0; i<sCount; i++)
			{
				SiPsiSDTGetService(sd->Data,&svr,i);
				if(svr.m_u16ServiceId == serviceID)
				{
					if(service != NULL)
						*service=svr;
					s32Ret = 0;
					break;
				}
			}
			sd=sd->next;
		}
	}
	else if(ts->pat && ts->pmt)
	{
		i=0;
		sd=ts->pmt->sections;
		while(sd)
		{
			if(SiPsiPMTGetServiceID(sd->Data) == serviceID)
			{
				if(service)
				{
					mwDebug("DVBTSFindService() - found service %d no SDT\r\n", serviceID);
					memset(service, 0, sizeof(*service));
					service->m_u16ServiceId = serviceID;
				}
				s32Ret = 0;
				break;
			}
			sd=sd->next;
		}
	}
	return s32Ret;
}

int DVBServiceGetTeletextInfo(dvb_service_t* handle, sipsi_teletextinfo_t *pInfo, unsigned int* pNum)
{
	unsigned int i, count, ttxcount=0;
	unsigned int componentTxtCnt = 0;
	sipsi_prog_element_t progelement[20]; 
	
	count = DVBTSGetServicePmtPidParams(handle,progelement);
	for (i=0;	i<MIN(count,20)&&ttxcount<*pNum;	i++)
	{
 		if (progelement[i].m_u8StreamType==SIPSI_ES_TYPE_PRIVATE_PES )			
 		{
			componentTxtCnt=SiPsiPMTGetTeletextInfo(&(progelement[i]), pInfo);
			if(componentTxtCnt)
			{
				pInfo+=componentTxtCnt;
				ttxcount+=componentTxtCnt;
			}
 		}
	}
	*pNum = ttxcount;
	return ttxcount;
}

int DVBGetCurrentNetworkName(unsigned char *networkname)
{
	SECTIONDATA*sd;
	unsigned char *section;
	int ret;
	PSECTIONDB  pNITDB = DVBTSDBGetNITDB();
	
	if (pNITDB && networkname)
	{
		sd=pNITDB->sections;
		while(sd)
		{
			section=sd->Data;
			ret = SiPsiNITGetNetworkname(section,networkname,NULL);
			if (ret>=0)
			{
				mwConvertString(networkname, DVBStringLen(networkname), NULL);
				mwDebug("DVBGetCurrentNetworkName() - networkname = %s\r\n", networkname);
				return 0;
			}
			sd=sd->next;
		}
	}
	return -1;
}

int DVBGetCurrentNetworkID(unsigned short *pNetworkID)
{
	SECTIONDATA*sd;
	unsigned char *section;
	int ret;
	PSECTIONDB  pNITDB;

	pNITDB = DVBTSDBGetNITDB();
	if(pNITDB && pNetworkID)
	{
		sd=pNITDB->sections;
		while(sd)
		{
			section=sd->Data;
			*pNetworkID = SiPsiNITGetNetID(section);	
			mwDebug("DVBGetCurrentNetworkID() - networkid=0x%x\r\n", *pNetworkID);
			if (*pNetworkID>=0)
				return 0;
			sd=sd->next;
		}
	}
	return -1;
}

int DVBTSGetServiceInfo(dvb_service_t* handle, sipsi_dvbservice_t *service)
{
	int s32Ret = -1;
	TSDATA *ts;

	if(handle && service)
	{
		ts = DVBTSDBSearchTS(handle->netId, handle->tsId, handle->frequence);
		s32Ret = DVBTSFindService(ts, handle->serviceId, service);
		if(s32Ret == -1)
		{
			mwError("DVBTSGetServiceInfo() - find service[%d, %d, %d, %d] not found int TS dbase\r\n", handle->frequence, handle->netId, handle->tsId, handle->serviceId);	
		}
	}
	else
	{
		mwError("DVBTSGetServiceInfo() - receive error param\r\n");
	}
	
	return s32Ret;
}

int DVBTSGetServiceType(dvb_service_t* handle, unsigned int* pu32Type)
{
	sipsi_dvbservice_t svr;
	unsigned char *p;
	int s32Ret;

	if(pu32Type)
	{
		s32Ret = DVBTSGetServiceInfo(handle, &svr);
		if(s32Ret==0 && svr.m_pu8Descriptors)
		{
			p = SiPsiFindDescriptor(svr.m_pu8Descriptors, svr.m_u16DescriptorLoopLength, SIPSI_DESCTAG_SERVICE);
			if(p)
			{
				*pu32Type = p[2];
				s32Ret = 0;
			}
			else
			{
				s32Ret = -1;
			}
		}
	}
	
	return s32Ret;
}

int DVBTSGetTunerParam(dvb_service_t* handle, dvb_tuner_t* pstTunerParams)
{
	TSDATA *ts;
	int ret;

	ts = DVBTSDBSearchTS(handle->netId,handle->tsId, handle->frequence);
	if(ts)
	{
		memcpy(pstTunerParams, &ts->tunerParams, sizeof(ts->tunerParams));
		ret = 0;
	}
	else
	{
		ret = -1;
	}

	return ret;
}

int DVBServiceGetAudioLangInfo(dvb_service_t* handle, AUDIOLANGINFO* pAudioInfo, unsigned int* pNum)
{
	int i,count;
	unsigned int j = 0,k=1;
	sipsi_prog_element_t progelement[20];
	unsigned char* pLangDescritor;

	count = DVBTSGetServicePmtPidParams(handle, progelement);
	for (i=0;	i<MIN(count,20)&&j<*pNum;	i++)
	{
 		if (progelement[i].m_u8StreamType==SIPSI_ES_TYPE_MPEG1_AUDIO || progelement[i].m_u8StreamType==SIPSI_ES_TYPE_MPEG2_AUDIO 
 			|| progelement[i].m_u8StreamType== SIPSI_ES_TYPE_AAC || progelement[i].m_u8StreamType== SIPSI_ES_TYPE_AAC1
 			|| progelement[i].m_u8StreamType== SIPSI_ATSC_DOLBY_DIGITAL)	//audio	
 		{
 			pAudioInfo[j].pid = progelement[i].m_u16ElementaryPid;
			memset(pAudioInfo[j].szLangCode, 0, sizeof(pAudioInfo[i].szLangCode));
			if(progelement[i].m_u16EsInfoLength)
			{
				pLangDescritor = SiPsiFindDescriptor(progelement[i].m_pu8Descriptors, progelement[i].m_u16EsInfoLength, 0x0a);
				if(pLangDescritor)
				{
					memcpy(pAudioInfo[j].szLangCode, pLangDescritor+2, 3);
					dvb_strupr(pAudioInfo[j].szLangCode);
					j++;
				}
			}
 		}

 		if (progelement[i].m_u8StreamType==SIPSI_ES_TYPE_PRIVATE_PES )
 		{
			if(SiPsiFindDescriptor(progelement[i].m_pu8Descriptors, progelement[i].m_u16EsInfoLength, SIPSI_DESCTAG_AC3))
			{
	 			pAudioInfo[j].pid = progelement[i].m_u16ElementaryPid;
				memset(pAudioInfo[j].szLangCode, 0, sizeof(pAudioInfo[i].szLangCode));
				{
					char szLangCode[10];
					pLangDescritor = SiPsiFindDescriptor(progelement[i].m_pu8Descriptors, progelement[i].m_u16EsInfoLength, 0x0a);
					if(pLangDescritor)
					{
						memset(szLangCode,0,10);
						memcpy(szLangCode, pLangDescritor+2, 3);
						dvb_strupr(szLangCode);
						sprintf(pAudioInfo[j].szLangCode, "%s ",szLangCode);
					}
					else
					{
						sprintf(pAudioInfo[j].szLangCode, "LANG%d", k++);
					}
				}
				j++;
			}
 		} 		
	}
	*pNum = j;
	if(j>0)
		return 0;
	return -1;
}

int DVBServiceGetSubtitleInfo(dvb_service_t* handle, SUBTITLEINFO *pSubtitleInfo)
{
	int i,j,count;
	unsigned int k = 0;
	sipsi_prog_element_t progelement[20];
	unsigned char *des;

	count = DVBTSGetServicePmtPidParams(handle,progelement);
	for (i=0;	i<MIN(count,20)&&k<10;	i++)
	{
		j=0;
 		if (progelement[i].m_u8StreamType==SIPSI_ES_TYPE_PRIVATE_PES )		//subtitle	
 		{
 			des=SiPsiFindDescriptor(progelement[i].m_pu8Descriptors,progelement[i].m_u16EsInfoLength, SIPSI_DESCTAG_SUBTITLING);
			if (des!=NULL)	
			{
				int descriptor_length=des[1];
				des+=2;
				while (descriptor_length >0)
				{
					memcpy(pSubtitleInfo->SutTitleDesc[j].Language,des,3);
					pSubtitleInfo->SutTitleDesc[j].Language[3]=0;
					dvb_strupr(pSubtitleInfo->SutTitleDesc[j].Language);
					pSubtitleInfo->SutTitleDesc[j].subtitling_type=des[3];
					pSubtitleInfo->SutTitleDesc[j].composition_page_id=(des[4]<<8)+des[5];
					pSubtitleInfo->SutTitleDesc[j].ancillary_page_id=(des[6]<<8)+des[7];
					descriptor_length-=8;
					des+=8;
					j++;
				}
				pSubtitleInfo->DescCount=j;
				pSubtitleInfo->pid=progelement[i].m_u16ElementaryPid;
				pSubtitleInfo++;
				k++;
			}
 		}
	}
	if(k>=0)
		return k;
	return -1;
}

